# 与51题基本完全一样
from functools import reduce

class Solution:
    def could_set(self, res, i, j):
        if i == 0:
            return True
        and_func = lambda x,y: x and y
        # 竖线
        collumn = reduce(and_func, [row[j] == '.' for row in res[:i]])
        # 左上斜线 
        left_line = reduce(and_func, [res[i-k][j-k] == '.' for k in range(i+1) if j - k >= 0])
        # 右上斜线
        right_line = reduce(and_func, [res[i-k][j+k] == '.' for k in range(i+1) if j + k < self.panel_size])
        return collumn and left_line and right_line

    def _NQueens(self, panel, i):
        if i == self.panel_size:
            self.res.append(panel.copy())
            return
        for j in range(self.panel_size):
            if self.could_set(panel, i, j):
                panel[i] = '.'*j + 'Q' + '.' * (self.panel_size-j-1)
                self._NQueens(panel, i+1)
                panel[i] = '.'*self.panel_size

    def totalNQueens(self, n: int) -> 'List[List[str]]':
        panel = ['.'*n] * n
        self.panel_size = n
        self.res = []
        self._NQueens(panel, 0)
        return len(self.res)
